﻿using AntlrTS.LangFundmental;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AntlrTS
{
    public interface Visitor
    {
        void Visit(LetExpr expr);
        void Visit(IfElseExpr expr);
        void Visit(MatchExpr expr);

        void Visit(PatternBody patternBody);

        void Visit(CaseExpr caseExpr);

        void Visit(ConstantExpr constantExpr);

        void Visit(AssignMentExpr assignMentExpr);
    }

    public class EveluableExpr:LangObject
    {
        Scope currentScope;
    }

    public class AssignMentExpr:EveluableExpr
    {
        public List<TSFunction> funcs;
        public void Accept(Visitor visitor)
        {
            visitor.Visit(this);
        }
    }

    public class LetExpr:EveluableExpr
    {
        public EveluableExpr elv;
        public List<TSFunction> variables;
        public void Accept(Visitor visitor)
        {
            visitor.Visit(this);
        }
    }

    public class IfElseExpr:EveluableExpr
    {
        public EveluableExpr ifExpr;
        public EveluableExpr thenExpr;
        public EveluableExpr elseExpr;
        public void Accept(Visitor visitor)
        {
            visitor.Visit(this);
        }
    }

    public class PatternBody:EveluableExpr
    {
        public Dictionary<List<LangObject>, EveluableExpr> patterns=new Dictionary<List<LangObject>,EveluableExpr>();

        public void Accept(Visitor visitor)
        {
            visitor.Visit(this);
        }
    }

    public class MatchExpr:EveluableExpr
    {
        public List<Variable> parameterVariable=new List<Variable>();
        public List<TSFunction> whereBlockVariable=new List<TSFunction>();
        public PatternBody patternBody=new PatternBody();

        public void Accept(Visitor visitor)
        {
            visitor.Visit(this);
        }
    }
    public class CaseExpr:EveluableExpr
    {
        public List<Variable> parameterVariable = new List<Variable>();
        public List<TSFunction> whereBlockVariable = new List<TSFunction>();
        public PatternBody patternBody = new PatternBody();
        public void Accept(Visitor visitor)
        {
            visitor.Visit(this);
        }
    }
    public class ConstantExpr : EveluableExpr
    {
        public Constant constant;
        public void Accept(Visitor visitor)
        {
            visitor.Visit(this);
        }
    }

    public class Parameters:LangObject
    {
       public List<OperatorExpr> patameters = new List<OperatorExpr>();
    }

    public class FunctionApp:LangObject
    {
        public FunctionName name=new FunctionName();
        public List<Parameters> parameter = new List<Parameters>();
        /*例如f()() 应该含有两个空的List*/
    }

   

    public class OperatorExpr:EveluableExpr
    {
        public enum Operators{ NOT , MUL,DIV,  ADD,SUB, AND,OR, LE,GE,EQ,NE}

        public List<Operators> ops=new List<Operators>();

        public List<OperatorExpr> opexprs = new List<OperatorExpr>();

        public LangObject constantOrFunctionApp = null;
    }


    public class TSFunction:Variable
    {
        Scope currentScope;
        public bool isFunctionDefs=false;
        public TSFunction() { isFunction = true; }
        public TSFunction(string name) { isFunction = true; functionName = rawStringName = name; }
        public string functionName{
            get { return rawStringName; }
            set { rawStringName = value; }
        }

        public List<string> moduleName;

        public List<Variable> parameterVariable = new List<Variable>();
        public int parameterCount { get { return parameterVariable.Count; } }
        public EveluableExpr elv;
        public int parametersCount()
        {
            return parameterVariable.Count;
        }
    }

}
